{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**问题：**\n",
    "假设你正在为一个电影推荐系统设计一个简单的KNN算法。我们有以下一些用户的电影评分数据，数据由两个特征组成：用户对电影A和电影B的评分，分别在1-5之间。用户的标签（电影类型偏好）是动作片（标签0）或者是喜剧片（标签1）。我们有一个新用户，他给电影A评分为3，电影B评分为4。请问这个用户可能偏好哪种类型的电影？\n",
    "\n",
    "**数据：**\n",
    "\n",
    "| 用户   | 电影A评分 | 电影B评分 | 偏好类型 |\n",
    "| ------ | --------- | --------- | -------- |\n",
    "| 用户1  | 5         | 1         | 动作片   |\n",
    "| 用户2  | 4         | 2         | 动作片   |\n",
    "| 用户3  | 2         | 5         | 喜剧片   |\n",
    "| 用户4  | 1         | 4         | 喜剧片   |\n",
    "| 用户5  | 3         | 2         | 动作片   |\n",
    "| 用户6  | 2         | 5         | 喜剧片   |\n",
    "\n",
    "你需要做以下步骤：\n",
    "1. 构造数据\n",
    "2. 创建KNN模型\n",
    "3. 使用数据训练模型\n",
    "4. 预测新用户的喜好"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 0. 引入核心包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.neighbors import KNeighborsClassifier"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = np.array([[5, 1], \n",
    "              [4, 2],  \n",
    "              [2, 5],  \n",
    "              [1, 4],\n",
    "              [3, 2],\n",
    "              [2, 5]\n",
    "              ])#TODO\n",
    "\n",
    "y = np.array([0, 0, 1, 1,0,1])#TODO  # 0表示动作片，1表示喜剧片"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 创建 KNN 模型\n",
    "k = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn = KNeighborsClassifier(n_neighbors=1)  #TODO"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier(n_neighbors=1)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;KNeighborsClassifier<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\">?<span>Documentation for KNeighborsClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>KNeighborsClassifier(n_neighbors=1)</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "KNeighborsClassifier(n_neighbors=1)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn.fit(X, y)# TODO"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 用模型推理(预测)用户的喜好"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_user = np.array([[3, 4]])\n",
    "prediction = prediction = knn.predict(new_user)#TODO"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. 数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkUAAAHJCAYAAACL5E3/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABu90lEQVR4nO3deVxU9f7H8dewg4BriAguueG+L6SlZu63IMu6aKmpdSstrdTSrFwyKyu1X2Wmqd2KLEu9lZqR5YJauVFqXnPHBTXNQEQRmfP7g8vEyIAMzDAwvp+PBw+dc77nez6fOTPy8Xu+5xyTYRgGIiIiItc5D1cHICIiIlIaqCgSERERQUWRiIiICKCiSERERARQUSQiIiICqCgSERERAVQUiYiIiAAqikREREQAFUUiIiIigIoiEQ4fPozJZMJkMhXYbsiQIZhMJiZNmlQygTlATswmk4l//etf+bbLyMigUqVKlrZr164tuSD/JydWZ+577dq1lhxzfry8vAgNDSU6OpoffvjBafvOLSsri+eff546derg4+ODyWRiyJAhJbJvEcmfl6sDEJGSsWTJEv7v//4PHx+fPOtWrFjBuXPnXBCVa1StWpVevXoBcOnSJRITE/nyyy/56quvePvtt3nkkUecuv/Zs2czdepUwsLC6NevH35+fnTq1Mmp+xSRa1NRJHIdaNmyJTt27GDlypXExMTkWf/RRx/h6elJkyZN+OWXX0o+QGD69Ok888wz1KhRw+n7ioyMZNGiRZbXhmEwZcoUJk2axFNPPcVdd91FSEiI0/a/fPlyADZs2MCNN97otP2IiH10+kzkOhAbG4uHhwcff/xxnnV//fUXK1eupFu3boSGhrogumzVqlUjMjKSgICAEt+3yWTiueeeo06dOly8eJFvv/3Wqfs7duwYgAoikVJGRZFIMaWlpTF9+nSaN29O+fLlCQwMpE6dOvTv35/Vq1fnaZ+ens706dNp2bIlgYGBBAYG0qFDBz744AOb/ZtMJmrVqsXly5eZMmUKkZGR+Pr62hzxyU+1atW49dZb+frrr0lJSbFa99lnn5GRkcF9991XYB9Hjx7lX//6FzVr1sTX15eQkBD69evHli1brNpt374dk8lE+/bt8+3r//7v/zCZTDz55JOWZQXNKbL3PSsKDw8PmjdvDmTnCn/PQRoyZAgnT55k+PDhhIeH4+XlxaxZsyzbHj16lJEjR1KnTh38/PyoVKkS//jHP9i0aZPVPnJyPHToEIDV3KbDhw8XOd/CfEaK2mdWVhavvPIK9evXx9fXl4iICJ5++mkyMjJsbnfhwgVeeeUV2rRpQ3BwMOXKlSMyMpIRI0bw+++/52n/008/0b9/f6pVq4aPjw/h4eEMHz6cpKQkm/2LOJNOn4kUQ1ZWFrfddhs//fQTVapUoUuXLvj5+XHs2DFWrlxJuXLl6Nmzp6X96dOn6d69O7/++iuhoaF07twZwzDYtGkTQ4YMYevWrfzf//1fnv2YzWZiYmJYv349nTt3plmzZlSuXNmuWAcOHMh3333HF198wdChQy3LP/74YwICArjzzjttjiQB7Ny5k1tvvZUzZ87QoEED+vXrR1JSEsuWLeOrr74iLi6O/v37A9CqVSsiIyP5+eefOXDgAHXq1MnTX85+rlWIQdHfs6I4f/48AL6+vlbL//jjD9q2bcuVK1fo1KkTly5dsoxobd68mb59+3Lu3DkaNGhA3759+eOPP1i9ejXffPMNH3/8Mffeey+AZd7Q559/zoULFxg8eLBlH4GBgcXKt6DPSHHewwEDBrBy5Uq6dOlCgwYN2LBhA6+++irHjx/no48+smqbnJxM9+7d2b17NxUrVqRLly74+vpy8OBB3n33XerVq0f9+vUt7d955x0ee+wxANq2bcvNN9/M3r17ef/99/nyyy9Zt24dDRs2LOTRE3EAQ+Q6d+jQIQMwrvV1GDx4sAEYL7zwgmXZ999/bwBG27ZtjYsXL1q1T0lJMbZu3Wq1rE+fPgZgjBo1yrh06ZJl+cmTJ402bdoYgLFq1SqrbXJiq1u3rnHs2DG7csuJ+cMPPzRSU1MNf39/o2vXrpb1R44cMUwmkxEbG2sYhmH07NnTAIwffvjB0sZsNhtNmzY1AGPcuHGG2Wy2rPv8888NDw8PIzAw0Dhx4oRl+dSpUw3AmDJlSp6Y9u/fbwBGZGSkzVhz79swivae5eeHH34wAKNz58551p06dcoIDg42ACM+Pt6qPWDceeedNo9xtWrVDE9PT+Ojjz6yWrdlyxajYsWKRmBgoHH69GmrdTVr1sz38+aMz0hx+mzYsKGRnJxsWX7w4EGjQoUKBmDs37/faptu3boZgHHPPfcY58+ft1p36NAh45dffrG83rx5s+Hp6WlUr149z/dk/vz5BmC0b9/e5nsk4iwqiuS6V5yi6NNPPzUAY/To0dfcz44dOywFVFZWVp7127dvNwDjjjvusFqeE9uSJUsKl5CNmD/88EPDMAzjnnvuMTw8PCy/OF966SUDMFasWGEYhu2iKKfwq1GjhnH58uU8++jXr58BGC+++KJl2cGDB20WPoZhGJMnTzYAY+rUqTZjzb3vor5n+bFVFF28eNH48ccfjfbt2xuA0aBBA+PKlStW7X19fW0WGzNnzjQA46mnnrK5vzfeeMMAjDfeeMNqeX5FkTM+I8XtM6dAzG3kyJEGYCxcuNCy7KeffjIAIyQkxEhNTc2zzdWio6MNwPjqq69srr/jjjsMwNi+ffs1+xJxFM0pEimGFi1a4OHhwcKFC5k3bx5nz57Nt23O5N2YmBg8PPJ+9XLmevz888951plMJm6//fZix3vfffdhNpuJi4sDsk9jhYSE0KNHj3y32bBhAwD33HMP3t7eedbff//9Vu0AateuzU033cR///tftm/fbtU+59TZwIEDrxlvcd6zgqxbt84yl8ff358OHTrw008/UbduXZYvX46np6dV+1atWlG9evV84+vXr5/N/dx8880AhY7PGZ+R4vTp7e1N165d8yzPOQWWnJxsWfbdd98B2ZP6g4KCbOaXw2w2s2bNGgICAqxOL+dm73sn4ggqiuS6d62bNuYwDCNP+/r16/Pqq6+Snp7OQw89REhICM2bN+fJJ5/k119/tdo+ZyLts88+m+cGgjk/aWlpnDlzJs++Q0JC8sxzKYpevXpRuXJlPv74Y3bs2MHu3bu599578fLKf3rhiRMnAKhVq5bN9TnLjx8/brU8p+jJPU9p69at/P7779x0003Url37mvEW5z0rSNWqVRk8eDCDBw9m2LBhjBs3jqVLl/Lbb78RGRmZp31+twnIia9jx442Y2vbti1AoeNzxmekOH2GhobmKRABS9GTe7J1zuR0W3PIrnbmzBnS0tJIT0+33Lzy6p+xY8da2oqUFE20lute7kvA09PT870kPD09HYBy5cpZLX/qqae45557WL58OfHx8WzYsIGZM2cya9YsZs6cyahRo4Ds/x1D9mTbwvziyM3Pz8+u9vnx9vbmnnvuYc6cOUyYMAEo3GTnguRXVN57772MHj2axYsXM2PGDKtbAhRmlAiK954V5Or7FF1Lfu9/Tnx33313ns/F1fsrDGd8RorTp62RJUfIiSkwMJC77rqrwLaNGzd2SgwitqgokutepUqV8Pf35+LFixw8eJAmTZrYbHfw4EEAwsPD86yLiIjgscce47HHHuPKlSssXryYBx54gHHjxjFo0CAqVqxo2S4mJoannnrKeQldw3333cecOXP45ptvqF+/Pu3atSuwfVhYGABHjhyxuT5nJOLq00uVK1emZ8+efP3116xdu5bOnTuzePFivL29LVdjXUtpec/yEx4ezt69e3nmmWdo3bq1Q/oDx+ZbUu9hREQEAAcOHLhm2ypVquDn52c59VzY0VoRZ9PpM7nueXp60rFjRyD7cRe2HD16lMTERDw8PCxt8+Pl5cV9991H27ZtuXz5Mvv27QOge/fuACxbtsyB0dvvpptuonnz5lSuXNnq0vz85MztWLJkCVlZWXnW51yWndMut5wRobi4OL7//ntOnjxJz549C307gdLynuXH0fE5I9+Seg9vu+02AD755BPS0tIKbOvl5UWXLl1ITU1lzZo1To1LxB4qikTAcorr5Zdf5qeffrJal5KSwtChQzGbzfTr18/yP2KAH374ge+++85yOiDHoUOH2LNnDyaTyfI/9fbt29O9e3c2btzIiBEjSE1NzRPHL7/8wjfffOPo9PJITEzkzJkzPP3009ds26VLF5o2bcrhw4d5/vnnLXOrIPsX7dKlSwkMDLRZYEVHRxMUFMQXX3zBggULgMKfOoPS9Z7Z8q9//YuQkBBeffVV3nvvvTyfgytXrrB69Wp27dpVqP6ckW9JvYft2rWja9eunD59moceeogLFy5YrT98+DA7d+60vH722Wfx8PDggQcesHnDzrS0NBYsWMDFixeLFZeIXVx9+ZtIaTFu3DgDMDw8PIyoqChjwIABRt++fY3y5csbgNGkSZM895vJuST7hhtuMHr16mUMHDjQ6NGjh+Hr62sAxmOPPWbV/tSpU0bLli0NwKhQoYLRpUsXy34iIiIs95LJDTBq1qxZpJyuviT/Wmxdkm8YhvHrr78alStXtty3JjY21ujYsaMBGF5eXsann36ab5+DBg2yXN4dFBRkpKenFxjr1fsuynuWn4LuU1RQ+8GDB+fbZvPmzUaVKlUMwIiIiDB69+5tDBgwwLj11lst9/NZtmyZ1TYF3afIGZ8RR/e5cOHCPLenMAzDOHbsmNGg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nJ/HtGmWgsjzyhX+sWMH5mefdXVYDufOxxCUnztwVo45Z3qcyWVFkT1Pm84RGhqaZ0To1KlThIaG5rsfX19ffHNfyvs/3t7exT5Yt9S+hcqBlTmeetxqXtFF80Uumi9iwkR4cDi31L4FTw/3uRzYEe9daefuObpdflOnwuTJZL3wAl+3bMk/duzAc/Lk7H9D3HROkdsdw6sov7LP0TmWxPvlsonWOU+bTkxMtPy0adOGgQMHkpiYmKcgAoiKimLNmjVWy+Lj44mKiiqpsK14engyu9dsAExY32U35/WsXrPcqiASKXVyXWWWMzJkfvbZ7EnWzz+fvV5EpBBcNlJUmKdNDxo0iOrVqzN9+nQARo0aRefOnXn99dfp27cvixcvZuvWrbz33nslHn+Ofg378fk9nzPqm1GcTfv7cuDw4HBm9ZpFv4b9XBabiNu7+rL73BMxc0aInn/e+rWISD5cfvVZQZKSkiwPUwW46aabiIuLY+LEiUyYMIF69eqxfPnyPMVVSevXsB/RDaJZf2g9qbtSWTFghdudMhMpdQpzHyIVRiJih1JVFF39tGlbT5/u378//XNu2FaKeHp40qlGJ1buWkmnGp1UEIk4W1ZW4e5DlLM+S/cLE5GClaqiSESk0K7xcFcrGiESkUJw+R2tRUREREoDFUUiIiIiqCgSERERAVQUiYiIiAAqikREREQAFUUiIiIigIoiEREREUBFkYiIiAigokhEREQEUFEkIiIiAqgoEhEREQFUFImIiIgAKopEREREABVFIiIiIoCKIhERERFARZGIiIgIoKJIREREBFBRJCIiIgKoKBIREREBVBSJiIiIACqKRERERAAVRSIiIiKAiiIRERERQEWRiIiICKCiSERERARQUSQiIiICqCgSERERAVQUiYiIiADgZe8GTz75pM3lJpMJPz8/6tatS3R0NJUqVSp2cCIiIiIlxe6iaMeOHWzfvp2srCwaNGgAwO+//46npyeRkZG88847PPXUUyQkJNCoUSOHBywiIiLiDHafPouOjua2227jxIkTbNu2jW3btnHs2DG6d+9ObGwsx48f55ZbbuGJJ564Zl9z5syhWbNmBAcHExwcTFRUFKtWrcq3/aJFizCZTFY/fn5+9qYgIiIikofdI0UzZswgPj6e4OBgy7Ly5cszadIkevTowahRo3j++efp0aPHNfsK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iYiIiJQUu0eKNmzYwKZNm/Dx8bFaXqtWLY4fP+6wwERERERKkt0jRWaz2eaDX48dO0ZQUJBDghIREREpaXYXRT169GDWrFmW1yaTibS0NF544QX69OnjyNhERERESozdp89ef/11evbsSaNGjbh06RIDBgxg3759VKlShU8++cQZMYqIiIg4nd1FUXh4OL/88guLFy/m119/JS0tjWHDhjFw4ECridciIiIiZYndRRGAl5cX9913n6NjEREREXGZQhVFX375Jb1798bb25svv/yywLZ33HGHQwITERERKUmFKopiYmI4efIkISEhxMTE5NvOZDLZvDJNREREpLQrVFFkNptt/l1ERETEXdh9Sf7Ro0edEYeIiIiIS9ldFNWqVYvOnTszb948zp0754yYREREREqc3UXR1q1badeuHVOmTKFatWrExMTw+eefk5GR4Yz4REREREqE3UVRy5YtmTFjBklJSaxatYobbriBhx56iKpVqzJ06FBnxCgiIiLidHYXRTlMJhNdu3Zl3rx5fPfdd9SuXZsPPvjAkbGJiIiIlJgiF0XHjh3j1VdfpUWLFrRr147AwEDefvttR8YmIiIiUmLsvqP13LlziYuLY+PGjURGRjJw4ED+85//ULNmTWfEJyIiIlIi7C6KXnzxRWJjY3nzzTdp3ry5M2ISERERKXF2F0VJSUmYTCZnxCIiIiLiMnYXRSaTib/++ov333+fPXv2ANCoUSOGDRtG+fLlHR6giIiISEko0n2K6tSpw8yZM/nzzz/5888/mTlzJnXq1GH79u3OiFFERETE6eweKXriiSe44447mDdvHl5e2ZtfuXKF4cOHM3r0aNavX+/wIEVEREScze6iaOvWrVYFEYCXlxfjxo2jTZs2Dg1OREREpKTYffosODiYpKSkPMuPHj1KUFCQQ4ISERERKWl2F0X33nsvw4YN49NPP+Xo0aMcPXqUxYsXM3z4cGJjY50Ro4iIiIjT2V0Uvfbaa/Tr149BgwZRq1YtatWqxZAhQ7j77rt55ZVX7Opr+vTptG3blqCgIEJCQoiJiWHv3r0FbrNo0SJMJpPVj5+fn71piIiIiFixe06Rj48Ps2fPZvr06Rw4cACAOnXqEBAQYPfO161bx4gRI2jbti1XrlxhwoQJ9OjRg99++41y5crlu11wcLBV8aT7JomIiEhx2V0U5QgI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1U/58uVtbvPxxx8THh7OL7/8QmJiouXn9ddfZ9GiRWRlZdmV98aNG3n88cfp06cPjRs3xtfXlzNnzli18fb2trvfqzVo0IArV66wY8cOy7L9+/dz7ty5YvUrIkWnokhEbPL09GTPnj389ttvVqeAcpQrV45HHnmEsWPH8s033/Dbb7/x4IMPkp6ezrBhwyztatWqxU033cSwYcPIysrijjvuyHefAwcOpEqVKkRHR7NhwwYOHTrE2rVrefzxxzl27JjNbd5//33uvvtumjRpYvUzbNgwzpw5wzfffGNX3vXq1ePDDz9kz549/PTTTwwcOBB/f3+rNrVq1WLNmjWcPHmyyEVMZGQkt912Gw899BA///wzO3bs4KGHHrI5eiUiJUNFkYjkKzg4mODg4HzXv/zyy9x1113cf//9tGrViv3797N69eo882IGDhzIL7/8wp133pmnwMgtICCA9evXU6NGDfr160fDhg0ZNmwYly5dshnHtm3b+OWXX7jrrrvyrCtfvjzdunXj/ffftyPj7CLr3LlztGrVivvvv99yy4HcXn/9deLj44mIiMhzmwJ7/Pvf/6Zq1arccsst3HnnnTz44IMEBQXh5+dX5D5FpOhMhmEYrg5CRETg2LFjRERE8N1339GtWzdXhyNy3VFRJCLiIt9//z1paWk0bdqU5ORkxo0bx/Hjx/n999/zTNIWEefT1WciIi6SmZnJhAkTOHjwIEFBQdx00018/PHHKohEXEQjRSIiIiJoorWIiIgIoKJIREREBFBRJCIiIgKoKBIREREBVBSJiIiIACqKRERERAAVRSIiIiKAiiIRERERQEWRiIiICAD/DxijG6rhxuevAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.title(\"User Movie Preference\", size=15) \n",
    "plt.xlabel(\"Movie A rating\")\n",
    "plt.ylabel(\"Movie B rating\")\n",
    "plt.grid()\n",
    "\n",
    "# 绘制原始样本点，要求不同的影片喜好类别用不同的颜色标记\n",
    "# 提示: 用scatter散点图绘制，用它的参数c实现不同的类别用不同的颜色标记\n",
    "#TODO\n",
    "colors = ['blue', 'green']  # 动作片类用蓝色，喜剧片类用绿色\n",
    "for color, label in zip(colors, np.unique(y)):  \n",
    "    plt.scatter(X[y == label, 0], X[y == label, 1], c=color, label=f'Preference {label}')  \n",
    "plt.legend()  \n",
    "# 绘制新数据点，用红色x标记，大小为8\n",
    "# 提示：用plt.plot()绘制，用它的参数marker实现不同的标记符号\n",
    "#TODO\n",
    "plt.plot(new_user[:, 0], new_user[:, 1], 'rx', markersize=8)\n",
    "# 新数据最近邻索引为第一个最近邻的索引\n",
    "dist, idx = knn.kneighbors(new_user, n_neighbors=1)#TODO\n",
    "nearest_idx = idx.flatten()[0]\n",
    "nearest = nearest = X[nearest_idx]#TODO # 获取最近邻点的坐标，这是一个列表，第一个元素是x坐标，第二个元素是y坐标\n",
    "\n",
    "# 用红线标记新数据点与最近邻点的连接线\n",
    "# 提示：用plt.plot()绘制，用 r-- 实现红色虚线\n",
    "#TODO\n",
    "\n",
    "plt.plot([new_user[0, 0], nearest[0]], [new_user[0, 1], nearest[1]], 'r--')\n",
    "# 为每个点添加坐标文本  \n",
    "for x, y in zip(X[:, 0], X[:, 1]):\n",
    "    plt.text(x, y+0.1, f'({x}, {y})') \n",
    "\n",
    "# 为新数据点添加坐标文本\n",
    "plt.text(new_user[0,0], new_user[0,1]+0.1, f'({new_user[0,0]}, {new_user[0,1]})')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
